<template>
	<!-- Header: Display Name and IP -->
	<div class="info-header">
		<span class="name">{{ longname }}</span>
		<span class="ip">{{ ip }}</span>
		<el-button @click="change">change</el-button>
	</div>
	<div v-if="!showGraphModal" style="height: 100%;">
		<div class="container">
			<div class="left-side" id="network-topology" style="width: 100%; height: 90%;"></div>
			<div class="right-side">
				<div class="grid-container">
					<div class="grid-item">
						<div class="grid-title">Type</div>
						<div class="grid-content">{{ filteredInstances[0]?.nfType || 'null' }}</div>
					</div>
					<div class="grid-item">
						<div class="grid-title">nfServices</div>
						<div class="grid-content">{{ filteredInstances[0]?.nfServices?.length || 'null' }}</div>
					</div>
					<div class="grid-item">
						<div class="grid-title">plmn.mcc</div>
						<div class="grid-content">{{ filteredInstances[0]?.plmnList?.[0]?.mcc || 'null' }}</div>
					</div>
					<div class="grid-item">
						<div class="grid-title">plmn.mnc</div>
						<div class="grid-content">{{ filteredInstances[0]?.plmnList?.[0]?.mnc || 'null' }}</div>
					</div>
					<div class="grid-item">
						<div class="grid-title">sNssais.sst</div>
						<div class="grid-content">{{ filteredInstances[0]?.sNssais?.[0]?.sst || 'null' }}</div>
					</div>
					<div class="grid-item">
						<div class="grid-title">sNssais.sd</div>
						<div class="grid-content">{{ filteredInstances[0]?.sNssais?.[0]?.sd || 'null' }}</div>
					</div>
					<div class="grid-item">
						<div class="grid-title">Status</div>
						<div class="grid-content">{{ filteredInstances[0]?.nfStatus || 'null' }}</div>
					</div>
					<div class="grid-item">
						<div class="grid-title">IPv4Address</div>
						<div class="grid-content">{{ filteredInstances[0]?.ipv4Addresses?.[0] || 'null' }}</div>
					</div>
				</div>
			</div>
		</div>
	</div>
	<!-- Display Graph Here -->
	<div v-else>
		<el-icon class="return-icon" @click="closeGraph">
			<Close />
		</el-icon>
		<div class="graph-modal">
			<div v-if="selectedGraph === 'input'">
				<Input :data="ioData" />
			</div>
			<div v-if="selectedGraph === 'output'">
				<Output :data="ioData" />
			</div>
			<div v-if="selectedGraph === 'cpu'">
				<CPU :data="cpuData" />
			</div>
			<div v-if="selectedGraph === 'gpu'">
				<Gpu :data="gpuData" />
			</div>
			<div v-if="selectedGraph === 'gpurate'">
				<GpuRate :data="gpuRate" />
			</div>
			<div v-if="selectedGraph === 'memory'">
				<Memory :data="memData" />
			</div>
			<div v-if="selectedGraph === 'diskread'">
				<DiskRead :data="diskRead" />
			</div>
			<div v-if="selectedGraph === 'diskwrite'">
				<DiskWrite :data="diskWrite" />
			</div>

		</div>
	</div>
</template>

<script>
import CPU from "./CPUGraph.vue";
import Memory from "./MemoryGraph.vue";
import Gpu from "./GpuGraph.vue";
import Input from "./InputGraph.vue";
import Output from "./OutputGraph.vue";
import GpuRate from "./GpuRateGraph.vue";
import DiskRead from "./DiskReadGraph.vue";
import DiskWrite from "./DiskWriteGraph.vue";
import axios from 'axios';
import * as echarts from 'echarts';

export default {
	components: {
		CPU,
		Memory,
		Gpu,
		Input,
		Output,
		GpuRate,
		DiskRead,
		DiskWrite
	},
	props: {
		name: {
			type: String,
			default: "",
		}
	},
	data() {
		return {
			data: [],
			cpuData: [],
			memData: [],
			gpuData: [],
			gpuRate: [],
			diskRead: [],
			diskWrite: [],
			ioData: [],
			jsonData: {},
			filteredInstances: {},
			ip: "",
			longname: "",
			intervalId: null,
			showGraphModal: false,
			selectedGraph: null,
			option: {
				tooltip: {},
				series: [
					{
						type: 'graph',
						layout: 'none',
						data: [
							{ name: '通', x: 200, y: 100, symbol: 'image://' + require('@/assets/icon/rect.png'), symbolSize: [60, 60], label: { fontSize: 18 } },
							{ name: '算', x: 100, y: 200, symbol: 'image://' + require('@/assets/icon/rect.png'), symbolSize: [60, 60], label: { fontSize: 18 } },
							{ name: '存', x: 300, y: 200, symbol: 'image://' + require('@/assets/icon/rect.png'), symbolSize: [60, 60], label: { fontSize: 18 } },
							{ name: 'Input', x: 150, y: 0, symbol: 'image://' + require('@/assets/icon/circle.png'), symbolSize: [70, 70] },
							{ name: 'Output', x: 250, y: 0, symbol: 'image://' + require('@/assets/icon/circle.png'), symbolSize: [70, 70] },
							{ name: 'CPU', x: 0, y: 150, symbol: 'image://' + require('@/assets/icon/circle.png'), symbolSize: [70, 70] },
							{ name: 'GPU', x: 0, y: 250, symbol: 'image://' + require('@/assets/icon/circle.png'), symbolSize: [70, 70] },
							{ name: 'GPU %', x: 80, y: 310, symbol: 'image://' + require('@/assets/icon/circle.png'), symbolSize: [70, 70] },
							{ name: 'Memory', x: 400, y: 150, symbol: 'image://' + require('@/assets/icon/circle.png'), symbolSize: [70, 70] },
							{ name: 'Disk Wr', x: 400, y: 250, symbol: 'image://' + require('@/assets/icon/circle.png'), symbolSize: [70, 70] },
							{ name: 'Disk Rd', x: 320, y: 310, symbol: 'image://' + require('@/assets/icon/circle.png'), symbolSize: [70, 70] },
						],
						links: [
							{ source: '通', target: '算', label: { show: true, formatter: '', position: 'middle', rotate: 0, color: 'white' } },
							{ source: '算', target: '存', label: { show: true, formatter: '', position: 'middle', rotate: 0, color: 'white' } },
							{ source: '存', target: '通', label: { show: true, formatter: '', position: 'middle', rotate: 0, color: 'white' } },
							{ source: '通', target: 'Input', label: { show: true, formatter: '', position: 'middle', rotate: 0, color: 'white' } },
							{ source: '通', target: 'Output', label: { show: true, formatter: '', position: 'middle', rotate: 0, color: 'white' } },
							{ source: '算', target: 'CPU', label: { show: true, formatter: '', position: 'middle', rotate: 0, color: 'white' } },
							{ source: '算', target: 'GPU', label: { show: true, formatter: '', position: 'middle', rotate: 0, color: 'white' } },
							{ source: '算', target: 'GPU %', label: { show: true, formatter: '', position: 'middle', rotate: 0, color: 'white' } },
							{ source: '存', target: 'Memory', label: { show: true, formatter: '', position: 'middle', rotate: 0, color: 'white' } },
							{ source: '存', target: 'Disk Wr', label: { show: true, formatter: '', position: 'middle', rotate: 0, color: 'white' } },
							{ source: '存', target: 'Disk Rd', label: { show: true, formatter: '', position: 'middle', rotate: 0, color: 'white' } },
						], // 初始化为空
						label: {
							show: true,
							position: 'inside',
							formatter: '{b}',
							color: 'black',
							fontSize: 14,
						},
						lineStyle: {
							curveness: 0,
							width: 2,
							color: 'white',
							opacity: 1
						},
					}
				],

			},
		};
	},
	methods: {
		async fetchData() {
			try {
				let that = this;
				await axios.get(`http://10.112.51.79:39898/get_nf_data?nf=${this.name}`)
					.then(function (res) {
						that.data = res.data;
					});
				this.cpuData = this.data.phy_cpu_list;
				this.memData = this.data.phy_mem_list;
				this.gpuData = this.data.gpu_list;
				this.ioData = this.data.net_io_list;
				this.gpuRate = this.data.gpu_rate;
				this.diskRead = this.data.disk_read;
				this.diskWrite = this.data.disk_write;
				this.ip = this.data.ip;
				this.longname = this.data.name;
				// console.log(this.gpuRate);
				if (!this.showGraphModal)
					this.updateChartData();
			} catch (error) {
				console.error('Failed to fetch data:', error);
			}
		},
		async loadData() {
			try {
				// 从 public 目录加载 data.json 文件
				const response = await fetch('/free5gc.json');
				if (response.ok) {
					this.jsonData = await response.json();
					this.filteredInstances = this.jsonData.filter(instance =>
						instance.nfType === this.name.toUpperCase()
					);
				} else {
					throw new Error('无法加载文件');
				}
			} catch (error) {
				console.error(error);
			}
		},
		initChart() {
			const container = document.getElementById('network-topology');
			if (container) {
				this.myChart = echarts.init(container);
				this.myChart.setOption(this.option);
			}
			// 添加点击事件
			this.myChart.on('click', this.handleNodeClick);
		},
		destroyChart() {
			if (this.myChart) {
				this.myChart.dispose(); // 销毁图表实例
			}
		},
		handleNodeClick(params) {
			// this.selectedGraph = params.name.toLowerCase(); // 更新点击的节点名称
			const componentMap = {
				CPU: 'CPU',
				Memory: 'Memory',
				GPU: 'Gpu',
				Input: 'Input',
				Output: 'Output',
				'GPU %': 'GpuRate',
				'Disk Wr': 'DiskWrite',
				'Disk Rd': 'DiskRead',
			};
			this.selectedGraph = componentMap[params.name].toLowerCase();
			if (this.selectedGraph) {
				// this.selectedGraph = componentName;
				this.showGraphModal = true;
			}
		},
		updateChartData() {
			this.myChart.setOption({
				series: [
					{
						type: 'graph',
						layout: 'none',
						data: [
							{ name: '通', x: 200, y: 100, symbol: 'image://' + require('@/assets/icon/rect.png'), symbolSize: [60, 60], label: { fontSize: 18 } },
							{ name: '算', x: 100, y: 200, symbol: 'image://' + require('@/assets/icon/rect.png'), symbolSize: [60, 60], label: { fontSize: 18 } },
							{ name: '存', x: 300, y: 200, symbol: 'image://' + require('@/assets/icon/rect.png'), symbolSize: [60, 60], label: { fontSize: 18 } },
							{ name: 'Input', x: 150, y: 0, symbol: 'image://' + require('@/assets/icon/circle.png'), symbolSize: [70, 70] },
							{ name: 'Output', x: 250, y: 0, symbol: 'image://' + require('@/assets/icon/circle.png'), symbolSize: [70, 70] },
							{ name: 'CPU', x: 0, y: 150, symbol: 'image://' + require('@/assets/icon/circle.png'), symbolSize: [70, 70] },
							{ name: 'GPU', x: 0, y: 250, symbol: 'image://' + require('@/assets/icon/circle.png'), symbolSize: [70, 70] },
							{ name: 'GPU %', x: 80, y: 310, symbol: 'image://' + require('@/assets/icon/circle.png'), symbolSize: [70, 70] },
							{ name: 'Memory', x: 400, y: 150, symbol: 'image://' + require('@/assets/icon/circle.png'), symbolSize: [70, 70] },
							{ name: 'Disk Wr', x: 400, y: 250, symbol: 'image://' + require('@/assets/icon/circle.png'), symbolSize: [70, 70] },
							{ name: 'Disk Rd', x: 320, y: 310, symbol: 'image://' + require('@/assets/icon/circle.png'), symbolSize: [70, 70] },
						].map(item => {
							if (item.name === 'CPU') {
								item.label = { show: true, position: 'inside', formatter: `CPU\n${this.cpuData[this.cpuData.length - 1]}m` };
							} else if (item.name === 'GPU') {
								item.label = { show: true, position: 'inside', formatter: `GPU\n${this.gpuData[this.gpuData.length - 1]}Mi` };
							} else if (item.name === 'Memory') {
								item.label = { show: true, position: 'inside', formatter: `Memory\n${this.memData[this.memData.length - 1]}Mi` };
							} else if (item.name === 'Input') {
								item.label = { show: true, position: 'inside', formatter: `Input\n${this.ioData[this.ioData.length - 1].toFixed(2)}Mb/s` };
							} else if (item.name === 'Output') {
								item.label = { show: true, position: 'inside', formatter: `Output\n${this.ioData[this.ioData.length - 1].toFixed(2)}Mb/s` };
							} else if (item.name == 'GPU %') {
								item.label = { show: true, position: 'inside', formatter: `GPU %\n${this.gpuRate[this.gpuRate.length - 1]}%` };
							} else if (item.name == 'Disk Wr') {
								item.label = { show: true, position: 'inside', formatter: `Disk Wr\n${this.diskWrite[this.diskWrite.length - 1]}B` };
							} else if (item.name == 'Disk Rd') {
								item.label = { show: true, position: 'inside', formatter: `Disk Rd\n${this.diskRead[this.diskRead.length - 1]}B` };
							}
							return item;
						}),
						links: [
							{ source: '通', target: '算', label: { show: true, formatter: '', position: 'middle', rotate: 0, color: 'white' } },
							{ source: '算', target: '存', label: { show: true, formatter: '', position: 'middle', rotate: 0, color: 'white' } },
							{ source: '存', target: '通', label: { show: true, formatter: '', position: 'middle', rotate: 0, color: 'white' } },
							{ source: '通', target: 'Input', label: { show: true, formatter: '', position: 'middle', rotate: 0, color: 'white' } },
							{ source: '通', target: 'Output', label: { show: true, formatter: '', position: 'middle', rotate: 0, color: 'white' } },
							{ source: '算', target: 'CPU', label: { show: true, formatter: '', position: 'middle', rotate: 0, color: 'white' } },
							{ source: '算', target: 'GPU', label: { show: true, formatter: '', position: 'middle', rotate: 0, color: 'white' } },
							{ source: '算', target: 'GPU %', label: { show: true, formatter: '', position: 'middle', rotate: 0, color: 'white' } },
							{ source: '存', target: 'Memory', label: { show: true, formatter: '', position: 'middle', rotate: 0, color: 'white' } },
							{ source: '存', target: 'Disk Wr', label: { show: true, formatter: '', position: 'middle', rotate: 0, color: 'white' } },
							{ source: '存', target: 'Disk Rd', label: { show: true, formatter: '', position: 'middle', rotate: 0, color: 'white' } },
						],
						label: {
							show: true,
							position: 'inside',
							formatter: '{b}',
							color: 'black',
							fontSize: 14,
						},
						lineStyle: {
							curveness: 0,
							width: 2,
							color: 'white',
							opacity: 1
						},
					}
				],
			});
		},
		showGraph(type) {
			this.selectedGraph = type;
			this.showGraphModal = true;
		},
		closeGraph() {
			this.showGraphModal = false;
			this.selectedGraph = null;
			if (this.myChart) {
				this.myChart.dispose();
			}
			// 重新初始化图表
			this.$nextTick(() => {
				this.initChart();
			});
		}
	},
	mounted() {
		this.$nextTick(async () => {
			await this.loadData();
			this.initChart(); // 确保容器已渲染后再初始化
			this.fetchData();
			this.intervalId = setInterval(this.fetchData, 1000);
		});
	},
	beforeDestroy() {
		if (this.intervalId) {
			clearInterval(this.intervalId);
		}
		if (this.myChart) {
			this.myChart.dispose(); // 销毁图表实例
		}
	}
};
</script>

<style scoped>
.container {
	display: grid;
	grid-template-columns: 4fr 1fr;
	/* 左侧2份，右侧1份 */
	width: 100%;
	height: 100%;
}

.left-side {
	width: 100%;
	height: 100%;
}

.right-side {
	display: flex;
	flex-direction: column;
	justify-content: flex-start;
	align-items: flex-start;
	padding: 10px;
}

.grid-container {
	display: grid;
	grid-template-columns: repeat(2, 1fr);
	grid-gap: 20px;
}

.grid-item {
	display: flex;
	justify-content: space-between;
	/* 左右排列 */
	align-items: center;
	/* 垂直居中对齐 */
	padding: 10px 15px;
	text-align: left;
	cursor: pointer;
	gap: 5px;
	background-color: #fbe5d6;
	border: #e97a1d solid 6px;
	border-radius: 12px;
	transition: transform 0.3s ease;
}

.grid-item:nth-child(7) {
	grid-column: 1 / 3;
	/* 占据第一列 */
}

.grid-item:nth-child(8) {
	grid-column: 1 / 3;
}

.grid-item:hover {
	transform: scale(1.1);
	/* 鼠标放上时放大1.05倍 */
}

.grid-title {
	font-size: 16px;
	font-weight: bold;
	color: black;
}

.grid-content {
	font-size: 14px;
	color: black;
}

.info-header {
	display: flex;
	justify-content: center;
	align-items: center;
	padding: 10px 20px;
	background-color: transparent;
	font-size: 18px;
	font-weight: bold;
	border-radius: 10px;
	max-width: 100%;
	text-shadow: 1px 1px 2px #000;
}

.name,
.ip {
	display: inline-block;
	margin: 0 10px;
	font-weight: bolder;
}

.name {
	color: #FF4545;
}

.ip {
	color: #4CAF50;
}

.info-header .name::before {
	content: 'Name: ';
	font-weight: bold;
}

.info-header .ip::before {
	content: 'IP: ';
	font-weight: bold;
}

.info-header:hover {
	background-color: #444;
	transition: background-color 0.3s;
	cursor: pointer;
}

.graph-modal {
	position: relative;
	padding: 20px;
	z-index: 1000;
}

.graph-modal button {
	margin-bottom: 20px;
}

.return-icon {
	position: absolute;
	left: 120px;
	top: -30px;
	background-color: transparent;
	color: cyan;
	font-size: 40px;
	cursor: pointer;
	outline: none;
	z-index: 1;
}

.return-icon::after {
	content: '关闭';
	/* 这是要显示的文字 */
	position: absolute;
	left: 100%;
	/* 将文字放置在图标的右侧 */
	top: 50%;
	transform: translateY(-50%);
	/* 垂直居中对齐 */
	white-space: nowrap;
	/* 防止文字换行 */
	background-color: transparent;
	/* 背景颜色 */
	color: cyan;
	/* 文字颜色 */
	padding: 2px 4px;
	/* 内边距 */
	border-radius: 4px;
	/* 圆角 */
	opacity: 0;
	/* 默认隐藏 */
	transition: opacity 0.3s;
	/* 过渡效果 */
	pointer-events: none;
	/* 防止伪元素影响点击事件 */
	font-size: 24px;
	font-weight: bold;
}

.return-icon:hover::after {
	opacity: 1;
	/* 鼠标悬停时显示 */
	pointer-events: auto;
	/* 鼠标悬停时允许点击 */
}
</style>